const db = require('../../lib/conn_oracle')
const exists = require('../../util/exists')

/**
 * 数据库批量处理前数据转换
 * @param {Array} arr 转换嵌套数组前的数组
 * @param {Number} id 角色或person的ID
 */
const dataHanding = (id,arr)=>{
    let newArr = []
    for(let i = 0;i < arr.length;i++){           
        newArr.push([Number(id),Number(arr[i])])          
    }
    // console.log(newArr)        
    return newArr
}

//查询权限组信息
exports.getRolesInfo = (req,res)=>{
    let rolesSql = `select * from c##wxw.vue_xfjcroles order by id`
    let datas
    async function fun(){
        let roles = await db.search2(rolesSql)
        datas = {roles}
        res.json({
            status:1,
            msg:"查询成功",
            datas
        })
    }
    fun()
}

//更新、新增、删除权限组
exports.editRoles = async (req,res)=>{
    let {submitType,submitForm} = req.body
    let {ID,ROLENAME,REMARK} = submitForm
    // console.log(submitType);
    // console.log(submitForm);
    let resDatas
    let handleSql
    let handleData
    let msg
    let submitTypeStr
    let status

    /**
     * 数据库处理函数
     * @param {String} sql  sql语句
     * @param {Array} data  参数（以数组形式传递，批量处理使用嵌套数组）
     */
    const cudFun = async (sql,data)=>{
        let newRoles = await db.writeTab(sql,data)
        resDatas = {newRoles}
        msg = resDatas.newRoles.errorNum ? `${submitTypeStr}失败，错误代码：ORA-` + resDatas.newRoles : `${submitTypeStr}成功`
        status = resDatas.newRoles.errorNum ? 0 : 1
        return {
            status,
            msg,
            resDatas
        } 
    }
    if(submitType === "update"){
        submitTypeStr = "更新"
        handleData = [ROLENAME,REMARK,ID]
        handleSql = `
                     update c##wxw.vue_xfjcroles
                     set
                     rolename = :ROLENAME,
                     remark = :REMARK
                     where id = :ID
                    `
        let newUsers = await cudFun(handleSql,handleData)
        res.json(newUsers)
    }else if(submitType === "add"){
        submitTypeStr = "新增"
        handleData = [ROLENAME,REMARK]
        handleSql = `
                     insert into c##wxw.vue_xfjcroles(id,rolename,remark)
                     values('',:ROLENAME,:REMARK)
                    `
        let newUsers = await cudFun(handleSql,handleData)
        res.json(newUsers)
    }else if(submitType === "delete"){
        submitTypeStr = "删除"
        handleData = [ID]
        handleSql = `delete c##wxw.vue_xfjcroles where id = :ID`
        let newUsers = await cudFun(handleSql,handleData)
        if(newUsers.msg.includes("失败")){
            newUsers.msg = "角色删除失败"           
            res.json(newUsers)
        }else{
            handleSql = `delete c##wxw.vue_xfjcrole_authority_middle where roleid = :ID`
            let newUsers = await cudFun(handleSql,handleData)
            if(newUsers.msg.includes("失败")){
                newUsers.msg = "角色对应权限组删除失败"           
                res.json(newUsers)
            }else{
                handleSql = `delete c##wxw.vue_xfjcuser_role_middle where roleid = :ID`
                let newUsers = await cudFun(handleSql,handleData)
                if(newUsers.msg.includes("失败")){
                    newUsers.msg = "角色对应权限组删除失败"           
                    res.json(newUsers)
                }else{
                    newUsers.msg = "角色删除成功"           
                    res.json(newUsers)
                }
            }
        }
    }   
}

//查询已有权限组
exports.hasAuthoritys = (req,res)=>{
    // console.log(req.query);
    let {id} = req.query
    id = Number(id)
    // console.log(id);
    let hasAuthoritysSql = `select *
                            from c##wxw.vue_xfjcrole_authority_middle
                            where roleid = ${id}
                            order by roleid,authorityid
                            `
    let datas 
    async function fun(){
        let hasAuths = await db.search2(hasAuthoritysSql)
        datas = {hasAuths}
        res.json({
            status:1,
            msg:"查询成功",
            datas
        })
    }
    fun()
}

//变更角色权限
exports.changeRoleAuth = async (req,res)=>{    
    let {roleId,submitForm} = req.body
    let {oldAuth , newAuth} = submitForm 
    // console.log(submitForm)
    
    let resDatas 
    let handleSql
    let handleData
    let msg
    let status
    let options = {
        autoCommit: true,
    }
    /**
     * 数据库变更处理
     * @param {String} changeType 修改类型：singleAdd(单个新增)、singleDel(单个权限删除)、AuthDel(同一权限组内所有权限均删除，变更后已无任何权限)、
     *                                     batchAdd(批量新增)、batchDel(批量删除)
     * @param {Array} data 数据，单个处理以数组形式传入、批量处理以嵌套数组形式传入
     * @param {Object} options ORACLE处理配置，批量处理时使用
     */
    const authChange = async (changeType,data,ops=options)=>{
        if(changeType === "AuthDel"){
            handleSql = `delete c##wxw.vue_xfjcrole_authority_middle where roleid = :roleId`
        }else{
            handleSql = changeType.includes("Add") ? `insert into c##wxw.vue_xfjcrole_authority_middle(id,roleid,authorityid) 
                                                        values('',:roleid,:authorityId)
                                                        `
                                                    : `delete c##wxw.vue_xfjcrole_authority_middle 
                                                        where roleid = :roleid
                                                        and authorityid = :authorityId
                                                        `
        }         
        let changeTypeStr = changeType.includes("Del") ? "删除" : "新增"
        let newRes = (changeType.includes("single") ||  changeType === "AuthDel") ? await db.writeTab(handleSql,data) : await db.writeManyTab2(handleSql,data,ops)                        
        resDatas = {newRes}            
        msg = (resDatas.newRes.errorNum || resDatas.newRes.code ) ? `${changeTypeStr}权限失败，错误代码：ORA-` + resDatas.newRes  
                                                                                : `${changeTypeStr}权限成功`
        status = (resDatas.newRes.errorNum || resDatas.newRes.code ) ? 0 : 1
        return {
            status,
            resDatas,
            msg
        }
    }

    if(!oldAuth && newAuth){
        handleData = dataHanding(roleId,newAuth)            
        let newAuthoritys = await authChange("batchAdd",handleData) // msg = "原无权限，现新增" 
        res.json(newAuthoritys)
    }else if(oldAuth && !newAuth){
        handleData = [Number(roleId)]     
        let newAuthoritys = await authChange("AuthDel",handleData) // msg = "原有权限，后无所有权限，删除" 
        res.json(newAuthoritys)
    }else{
        //长度相同，也需要判断权限明细是否有不同    
        let needDel = exists.exists(oldAuth,newAuth) //须删除
        let needAdd = exists.exists(newAuth,oldAuth) //须增加
        let ctStr 
        console.log(needDel);
        console.log(needAdd);       
        if(!needDel.length && !needAdd.length){
            msg = "权限未作修改"           
            status = 0
            res.json({
                status,
                msg
            })
        }else if((needDel.length && !needAdd.length) || (!needDel.length && needAdd.length)){
            if(needDel.length && !needAdd.length && needDel.length > 1){
                ctStr = "batchDel"
                handleData = dataHanding(roleId,needDel) 
            }else if(needDel.length && !needAdd.length && needDel.length === 1){
                ctStr = "singleDel"
                handleData = [Number(roleId),Number(needDel[0])]
            }else if(!needDel.length && needAdd.length && needAdd.length > 1){
                ctStr = "batchAdd"
                handleData = dataHanding(roleId,needAdd) 
            }else if(!needDel.length && needAdd.length && needAdd.length === 1){
                ctStr = "singleAdd"
                handleData = [Number(roleId),Number(needAdd[0])]
            } 
            let newAuthoritysDel = await authChange(ctStr,handleData)
            if(newAuthoritysDel.msg.includes("失败")){
                msg = "权限修改失败"           
                status = 0
                res.json({
                    status,
                    msg
                })
            }else{
                msg = "权限修改成功"           
                status = 1
                res.json({
                    status,
                    msg
                })
            }
        }else{
            //需要缩减和增加权限(先增加，后删除)
            ctStr = needAdd.length > 1 ? "batchAdd" : "singleAdd"
            handleData = needAdd.length > 1 ? dataHanding(roleId,needAdd) : [Number(roleId),Number(needAdd[0])]
            let newAuthoritysAdd = await authChange(ctStr,handleData)
            if(newAuthoritysAdd.msg.includes("失败")){
                msg = "权限修改失败"           
                status = 0
                res.json({
                    status,
                    msg
                })
            }else{
                ctStr = needDel.length > 1 ? "batchDel" : "singleDel"
                handleData = needDel.length > 1 ? dataHanding(roleId,needDel) : [Number(roleId),Number(needDel[0])]
                let newAuthoritysDel = await authChange(ctStr,handleData)
                if(newAuthoritysDel.msg.includes("失败")){
                    msg = "权限修改失败"           
                    status = 0
                    res.json({
                        status,
                        msg
                    })
                }else{
                    msg = "权限修改成功"           
                    status = 1
                    res.json({
                        status,
                        msg
                    })
                }
            }
        }       
    }   
}

//查询角色用户
exports.hasUsers = async (req,res)=>{
    let {id} = req.query
    id = Number(id)
    // console.log(id);
    let hasUsersSql = `select u.id,u.personid,u.username,u.realname,u.persongroup
                       from c##wxw.vue_xfjcusers u
                       where exists (
                                    select 1
                                    from c##wxw.vue_xfjcuser_role_middle ur
                                    where u.personid = ur.personid
                                      and ur.roleid = ${id}
                                    )                       
                      `
    let noHasUsersSql = `select u.id,u.personid,u.username,u.realname,u.persongroup
                        from c##wxw.vue_xfjcusers u
                        where not exists (
                                        select 1
                                        from c##wxw.vue_xfjcuser_role_middle ur
                                        where u.personid = ur.personid
                                            and ur.roleid = ${id}
                                        )                       
                        `
    let datas 
    let hasUsers = await db.search2(hasUsersSql)
    let noHasUsers = await db.search2(noHasUsersSql)
    datas = {
        hasUsers,
        noHasUsers
    }
    res.json({
        status:1,
        msg:"查询成功",
        datas
    })
}

//变更分配用户
exports.changeRoleUser = async (req,res)=>{
    // console.log(req.body)
    let {roleId,submitForm} = req.body
    let {needAdd,needDel} = submitForm
    let resDatas 
    let handleSql
    let handleData
    let msg
    let status
    let options = {
        autoCommit: true,
    }
    let dataChangeType
    /**
     * 数据库变更处理
     * @param {String} changeType 修改类型：singleAdd(单个新增)、singleDel(单个用户删除)
     *                                     batchAdd(批量新增)、batchDel(批量删除)
     * @param {Array} data 数据，单个处理以数组形式传入、批量处理以嵌套数组形式传入
     * @param {Object} options ORACLE处理配置，批量处理时使用
     */
    const userChange = async (changeType,data,ops=options)=>{
        handleSql = changeType.includes("Add") ? `insert into c##wxw.vue_xfjcuser_role_middle(id,roleid,personid) 
                                                    values('',:roleid,:personid)
                                                    `
                                                : `delete c##wxw.vue_xfjcuser_role_middle
                                                    where roleid = :roleid
                                                    and personid = :personid
                                                    `       
        let changeTypeStr = changeType.includes("Del") ? "移除" : "分配"
        let newRes = changeType.includes("single") ? await db.writeTab(handleSql,data) : await db.writeManyTab2(handleSql,data,ops)                        
        resDatas = {newRes}            
        msg = (resDatas.newRes.errorNum || resDatas.newRes.code ) ? `${changeTypeStr}用户失败，错误代码：ORA-` + resDatas.newRes  
                                                                                : `${changeTypeStr}用户成功`
        status = (resDatas.newRes.errorNum || resDatas.newRes.code ) ? 0 : 1
        return {
            status,
            resDatas,
            msg
        }
    }  

    if(!needAdd.length && !needDel.length){
        msg = "未重新分配"           
        status = 0
        res.json({
            status,
            msg
        })
    }
    if(!needAdd.length && needDel.length){
        handleData = needDel.length > 1 ? dataHanding(roleId,needDel) : [Number(roleId),Number(needDel[0])]   
        dataChangeType = needDel.length > 1 ? "batchDel" : "singleDel"        
        let newUsers = await userChange(dataChangeType,handleData) // 删除用户分配 
        res.json(newUsers)
    }
    if(needAdd.length && !needDel.length){
        handleData = needAdd.length > 1 ? dataHanding(roleId,needAdd) : [Number(roleId),Number(needAdd[0])]    
        dataChangeType = needAdd.length > 1 ? "batchAdd" : "singleAdd"   
        let newUsers = await userChange(dataChangeType,handleData) // 新增用户分配 
        res.json(newUsers)
    }
    if(needAdd.length && needDel.length){
        //先新增后删除
        handleData = needAdd.length > 1 ? dataHanding(roleId,needAdd) : [Number(roleId),Number(needAdd[0])]    
        dataChangeType = needAdd.length > 1 ? "batchAdd" : "singleAdd"   
        let newUsers = await userChange(dataChangeType,handleData) // 新增用户分配 
        if(newUsers.msg.includes("失败")){
            msg = "分配用户修改失败"           
            status = 0
            res.json({
                status,
                msg
            })
        }else{
            handleData = needDel.length > 1 ? dataHanding(roleId,needDel) : [Number(roleId),Number(needDel[0])]   
            dataChangeType = needDel.length > 1 ? "batchDel" : "singleDel"        
            let newUsers = await userChange(dataChangeType,handleData)
            if(newUsers.msg.includes("失败")){
                msg = "分配用户修改失败"           
                status = 0
                res.json({
                    status,
                    msg
                })
            }else{
                msg = "分配用户修改成功"           
                status = 1
                res.json({
                    status,
                    msg
                })
            }
        }
    }

}